package com.founder.chd_daily_query.service.impl;

import com.founder.chd_daily_query.service.AlarmService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.data.domain.Example;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
import org.springframework.stereotype.Service;

import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
import javax.xml.crypto.Data;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;

@Service
public class AlarmServiceImpl implements AlarmService {

    @Autowired
    ApplicationContext applicationContext;
    @Override
    public Object queryForAllByPage(String model, int page, int count) throws ClassNotFoundException {
        //反射生成对应的repo类型.Class
        Class<?> aClass = Class.forName("com.founder.chd_daily_query.repo.alarm." + model + "Repo");
        //IOC容器拿出对应的实例
        Object bean = applicationContext.getBean(aClass);
        JpaRepository repo =(JpaRepository)bean;
        PageRequest of = PageRequest.of(page, count);

        long rowCount = repo.count();
        Page all =  repo.findAll(of);
        List content = all.getContent();
        Map<String,Object> data =new HashMap<String,Object>();
        data.put("data",content);
        Map<String,Long> map=new HashMap<String, Long>();
        map.put("count",rowCount);
        List<Object> res =new ArrayList<Object>(Arrays.asList(new Object[]{data, map}));
        //res.add(map);
        return res;
    }

    @Override
    public Object queryForAlarmedByPage(String model, int page, int count,String startTime,String endTime) throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InstantiationException, InvocationTargetException {
        //反射生成对应的repo类型.Class
        Class<?> aClass = Class.forName("com.founder.chd_daily_query.repo.alarm." + model + "Repo");
        Class<?> entity = Class.forName("com.founder.chd_daily_query.entity.alarm." + model + "Entity");
        Object o = entity.newInstance();
        Method setStatus = entity.getMethod("setStatus",String.class);
        setStatus.invoke(o,"ALARM");
        //IOC容器拿出对应的实例
        Object bean = applicationContext.getBean(aClass);
        JpaRepository repo =(JpaRepository)bean;
        PageRequest of = PageRequest.of(page, count);
        Example<Object> exe = Example.of(o);

        if(null != startTime && null != endTime){
            return queryForAlarmedByPageAndTime(bean,of,startTime,endTime);
        }else{

            long rowCount = repo.count(exe);
            Page all =  repo.findAll(exe,of);
            List content = all.getContent();
            Map<String,Object> data =new HashMap<String,Object>();
            data.put("data",content);
            Map<String,Long> map=new HashMap<String, Long>();
            map.put("count",rowCount);
            List<Object> res =new ArrayList<Object>(Arrays.asList(new Object[]{data, map}));
            //res.add(map);
            return res;
        }
    }

    public Object queryForAlarmedByPageAndTime(Object bean, PageRequest of, String startTime, String endTime){
        JpaSpecificationExecutor repoa = (JpaSpecificationExecutor) bean;
        Specification  specification = new Specification() {
            @Override
            public Predicate toPredicate(Root root, CriteriaQuery criteriaQuery, CriteriaBuilder criteriaBuilder) {

                Date start = null;
                Date end = null;
                try {
                    start = new SimpleDateFormat("yyyy-MM-dd").parse(startTime);
                    end = new SimpleDateFormat("yyyy-MM-dd").parse(endTime);
                } catch (ParseException e) {
                    e.printStackTrace();
                }
                List<Predicate> list = new ArrayList<Predicate>();
                Predicate p1 = criteriaBuilder.between(root.get("createDate"),start,end);
                Predicate p2 = criteriaBuilder.equal(root.get("status"),"ALARM");
                list.add(criteriaBuilder.and(p1,p2));
                return criteriaBuilder.and(list.toArray(new Predicate[list.size()]));
            }
        };

        Page all = repoa.findAll(specification,of);
        long count = repoa.count(specification);
        List content = all.getContent();
        Map<String,Object> data =new HashMap<String,Object>();
        data.put("data",content);
        Map<String,Long> map=new HashMap<String, Long>();
        map.put("count",count);
        List<Object> res =new ArrayList<Object>(Arrays.asList(new Object[]{data, map}));
        return res;
    }

    public Object RelationQuery(String model, String field, String key) throws InvocationTargetException, IllegalAccessException, InstantiationException, NoSuchMethodException, ClassNotFoundException {
        Class<?> repoType = Class.forName("com.founder.chd_daily_query.repo.alarm." + model + "Repo");
        Class<?> entity = Class.forName("com.founder.chd_daily_query.entity.alarm." + model + "Entity");
        Method method = entity.getMethod("set" + field, String.class);
        Object o = entity.newInstance();
        method.invoke(o, String.valueOf(key));
        JpaRepository repo = (JpaRepository)this.applicationContext.getBean(repoType);
        Example<Object> of = Example.of(o);
        List all = repo.findAll(of);
        return all;
    }
}

